package com.cc.pms.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cc.pms.domain.vo.UserVo;
import com.cc.common.core.domain.R;
import com.cc.common.core.domain.entity.SysUser;
import com.cc.common.core.domain.model.LoginUser;
import com.cc.common.core.page.PageQuery;
import com.cc.common.core.page.PageVo;
import com.cc.common.utils.SecurityUtils;
import com.cc.common.utils.StringUtils;
import com.cc.framework.web.service.SysLoginService;
import com.cc.framework.web.service.TokenService;
import com.cc.pms.domain.UserTag;
import com.cc.pms.mapper.TagMapper;
import com.cc.pms.service.IUserService;
import com.cc.pms.service.IUserTagService;
import com.cc.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.cc.common.utils.SecurityUtils.getLoginUser;


@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private TagMapper tagMapper;

    @Resource
    private IUserTagService userTagService;

    @Resource
    private SysLoginService loginService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private TokenService tokenService;


    @Override
    public PageVo<UserVo> queryUserVoListByTagIds(PageQuery query, List<Long> tagIds) {
        Long userId = SecurityUtils.getUserId();
        // 若前端未传 tagIds，使用用户自身绑定的标签
        if (tagIds == null || tagIds.isEmpty()) {
            List<UserTag> userTagList = userTagService.queryTagByUserId(userId);
            tagIds = userTagList.stream().map(UserTag::getTagId).collect(Collectors.toList());
            if (tagIds.isEmpty()) {
                return PageVo.of(Collections.emptyList(), 0L);
            }
        }
        Page<UserVo> userVoPage = tagMapper.queryUserVoPageByTagId(new Page<>(query.getPageNum(), query.getPageSize()), userId, tagIds);
        return PageVo.of(userVoPage.getRecords(), userVoPage.getTotal());
    }

    @Override
    public PageVo<UserVo> queryUserVoListByUserName(PageQuery query, String username) {
        UserVo userVo = new UserVo();
        userVo.setUsername(username);
        Page<UserVo> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<UserVo> userVoPage = tagMapper.queryUserVoPageByName(page, username, SecurityUtils.getUserId());
        return PageVo.of(userVoPage.getRecords(), userVoPage.getTotal());
    }

    @Override
    public UserVo queryUserVoListByUserId(Long userId) {
        return tagMapper.queryUserByUserId(userId);
    }

    @Override
    public R<Map<String, String>> loginService(UserVo userVo) {
        if (userVo == null) {
            return R.fail(-1, "用户信息为空,登录失败");
        }

        SysUser sysUser = null;
        if (userVo.getPhonenumber() != null) {
            sysUser = sysUserService.selectUserByPhonenumber(userVo.getPhonenumber());
            if (sysUser == null) {
                return R.fail(-1, "电话号码输入错误,没有查询到用户信息");
            }
        } else if (userVo.getUserId() != null) {
            sysUser = sysUserService.selectUserById(userVo.getUserId());
            if (sysUser == null) {
                return R.fail(-1, "用户信息输入错误,没有查询到用户信息");
            }
        }
        if (sysUser == null || sysUser.getDelFlag().equals("2")) {
            return R.fail(-1, "用户信息不存在,登录失败");
        }
        String token = loginService.login(sysUser.getUserName(), userVo.getPassword(), null, null);
        Map<String, String> map = new HashMap<>();
        map.put("token", token);
        return R.ok(map);
    }

    @Override
    public R<Boolean> updatePassword(UserVo userVo) {
        if (userVo == null || userVo.getPassword() == null) {
            return R.fail(-1, "用户信息为空,修改失败");
        }
        SysUser sysUser = sysUserService.selectUserById(userVo.getUserId());
        if (sysUser == null || sysUser.getDelFlag().equals("2")) {
            return R.fail(-1, "用户信息不存在,修改失败");
        }

        String encryptPassword = SecurityUtils.encryptPassword(userVo.getPassword());
        sysUser.setPassword(encryptPassword);
        sysUserService.resetUserPwd(sysUser.getUserName(), sysUser.getPassword());
        return R.ok();
    }

    @Override
    public R<Boolean> forgetPassword(UserVo userVo) {
        if (userVo == null || userVo.getPhonenumber() == null) {
            return R.fail(-1, "用户信息为空,验证失败");
        }
        SysUser sysUser = sysUserService.selectUserById(userVo.getUserId());
        if (sysUser == null || sysUser.getDelFlag().equals("2")) {
            return R.fail(-1, "用户信息不存在,验证失败");
        }
        return sysUser.getPhonenumber() != null && sysUser.getPhonenumber().endsWith(userVo.getPhonenumber()) ? R.ok(true) : R.fail(-1, "电话校验失败");
    }

    @Override
    public R<Boolean> updateUser(UserVo user) {
        if (user == null) {
            return R.fail(-1, "用户信息提交为空,修改失败");
        }
        if (user.getPhonenumber() == null || user.getPhonenumber().isEmpty()) {
            return R.fail(-1, "电话号码不能为空");
        }

        LoginUser loginUser = getLoginUser();
        SysUser currentUser = loginUser.getUser();
        currentUser.setNickName(user.getNickName());
        currentUser.setAvatar(user.getAvatar());
        currentUser.setEmail(user.getEmail());
        currentUser.setPhonenumber(user.getPhonenumber());
        currentUser.setSex(user.getSex());
        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !sysUserService.checkPhoneUnique(currentUser))
        {
            return R.fail(-1 ,"修改用户'" + loginUser.getUsername() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail()) && !sysUserService.checkEmailUnique(currentUser))
        {
            return R.fail(-1 ,"修改用户'" + loginUser.getUsername() + "'失败，邮箱账号已存在");
        }
        if (sysUserService.updateUserProfile(currentUser) > 0)
        {
            // 更新缓存用户信息
            tokenService.setLoginUser(loginUser);
            return R.ok();
        }
        return R.fail(-1 ,"修改个人信息异常，请联系管理员");
    }

    @Override
    public R<Map<String, Long>> registerUser(UserVo userVo) {
        if (userVo == null) {
            return R.fail(-1, "用户信息为空,注册失败");
        }
        if (userVo.getNickName() == null) {
            return R.fail(-1, "昵称不能为空");
        }
        if (userVo.getUsername() == null) {
            return R.fail(-1, "用户名不能为空");
        }
        if (userVo.getPassword() == null) {
            return R.fail(-1, "密码不能为空");
        }
        if (userVo.getPhonenumber() == null) {
            return R.fail(-1, "电话号码不能为空");
        }

        // 判断电话吗是否存在
        if (!sysUserService.checkPhoneUnique(userVo.getPhonenumber())) {
            return R.fail(-1, "电话码已被其它用户占用,不可再次注册使用");
        }

        SysUser sysUser = sysUserService.selectUserByUserName(userVo.getUsername());
        if (sysUser != null) {
            return R.fail(-1, "用户名已存在");
        } else {
            sysUser = new SysUser();
            sysUser.setUserName(userVo.getUsername());
            sysUser.setNickName(userVo.getNickName());
            sysUser.setAvatar(userVo.getAvatar());
            if (userVo.getAvatar() == null || userVo.getAvatar().trim().isEmpty()) {
                sysUser.setAvatar("/api/pms/images/default.jpg");
            }
            sysUser.setEmail(userVo.getEmail());
            sysUser.setSex(userVo.getSex());
            sysUser.setPhonenumber(userVo.getPhonenumber());
            sysUser.setStatus("0");
            String encryptPassword = SecurityUtils.encryptPassword(userVo.getPassword());
            sysUser.setPassword(encryptPassword);
            sysUserService.insertUser(sysUser);
            Map<String, Long> map = new HashMap<>();
            map.put("userId", sysUser.getUserId());
            return R.ok(map);
        }
    }
}
